package com.tools.common.object.json.deserializer;

import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.tools.common.container.OwnList;
import com.tools.common.container.OwnSet;
import com.tools.common.container.r.OnlyReadArrayList;
import com.tools.common.container.r.OnlyReadHashSet;
import com.tools.common.container.r.OnlyReadLinkedSet;
import com.tools.common.container.r.OnlyReadTreeSet;
import com.tools.common.object.Note;
import com.tools.common.object.json.DeserializerHandler;
import com.tools.common.object.json.JsonKit;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentSkipListSet;

/**
 * 类似数组容器类型的反序列化处理器
 * */
@Note("类似数组容器类型的反序列化处理器")
public class RowTypeHandler {

    private RowTypeHandler() {}


    @Note("处理、转换获取自定义容器实例 OwnList")
    public static StdDeserializer<OwnList> ownListDeserializer() {
        return new StdDeserializer<OwnList>(OwnList.class) {
            @Override
            public OwnList deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken jsonToken = jsonParser.currentToken();
                if(jsonToken == null) {
                    jsonToken = jsonParser.nextToken();
                }
                if(jsonToken == JsonToken.START_ARRAY) {
                    OwnList ownList = new OwnList<>();
                    JsonKit.ownRowParseToken(jsonParser, ownList);
                    return ownList;
                }
                throw new ClassCastException("无法将对象类型的 JSON 字符串转为 com.tools.common.container.OwnList 实例");
            }
        };
    }


    @Note("处理、转换获取自定义容器实例 OwnSet")
    public static StdDeserializer<OwnSet> ownSetDeserializer() {
        return new StdDeserializer<OwnSet>(OwnSet.class) {
            @Override
            public OwnSet deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken jsonToken = jsonParser.currentToken();
                if(jsonToken == null) {
                    jsonToken = jsonParser.nextToken();
                }
                if(jsonToken == JsonToken.START_ARRAY) {
                    OwnSet ownSet = new OwnSet<>();
                    JsonKit.ownRowParseToken(jsonParser, ownSet);
                    return ownSet;
                }
                throw new ClassCastException("无法将对象类型的 JSON 字符串转为 com.tools.common.container.OwnList 实例");
            }
        };
    }


    @Note("处理、转换获取只读的 ArrayList 实例 OnlyReadArrayList")
    public static StdDeserializer<OnlyReadArrayList> onlyReadArrayListDeserializer() {
        return new StdDeserializer<OnlyReadArrayList>(OnlyReadArrayList.class) {
            @Override
            public OnlyReadArrayList deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken jsonToken = jsonParser.currentToken();
                if(jsonToken == null) {
                    jsonToken = jsonParser.nextToken();
                }
                if(jsonToken == JsonToken.START_ARRAY) {
                    List list = new ArrayList<>();
                    JsonKit.collectionParseToken(jsonParser, list);
                    return new OnlyReadArrayList<>(list);
                }
                throw new ClassCastException("无法将对象类型的 JSON 字符串转为 com.tools.common.container.r.OnlyReadArrayList 实例");
            }
        };
    }


    @Note("处理、转换获取只读的 HashSet 实例 OnlyReadHashSet")
    public static StdDeserializer<OnlyReadHashSet> onlyReadHashSetDeserializer() {
        return new StdDeserializer<OnlyReadHashSet>(OnlyReadHashSet.class) {
            @Override
            public OnlyReadHashSet deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken jsonToken = jsonParser.currentToken();
                if(jsonToken == null) {
                    jsonToken = jsonParser.nextToken();
                }
                if(jsonToken == JsonToken.START_ARRAY) {
                    Set set = new HashSet<>();
                    JsonKit.collectionParseToken(jsonParser, set);
                    return new OnlyReadHashSet<>(set);
                }
                throw new ClassCastException("无法将对象类型的 JSON 字符串转为 com.tools.common.container.r.OnlyReadHashSet 实例");
            }
        };
    }


    @Note("处理、转换获取只读的 LinkedHashSet 实例 OnlyReadLinkedSet")
    public static StdDeserializer<OnlyReadLinkedSet> onlyReadLinkedSetDeserializer() {
        return new StdDeserializer<OnlyReadLinkedSet>(OnlyReadHashSet.class) {
            @Override
            public OnlyReadLinkedSet deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken jsonToken = jsonParser.currentToken();
                if(jsonToken == null) {
                    jsonToken = jsonParser.nextToken();
                }
                if(jsonToken == JsonToken.START_ARRAY) {
                    Set set = new LinkedHashSet<>();
                    JsonKit.collectionParseToken(jsonParser, set);
                    return new OnlyReadLinkedSet<>(set);
                }
                throw new ClassCastException("无法将对象类型的 JSON 字符串转为 com.tools.common.container.r.OnlyReadLinkedSet 实例");
            }
        };
    }


    @Note("处理、转换获取只读的 TreeSet 实例 OnlyReadTreeSet")
    public static StdDeserializer<OnlyReadTreeSet> onlyReadTreeSetDeserializer() {
        return new StdDeserializer<OnlyReadTreeSet>(OnlyReadTreeSet.class) {
            @Override
            public OnlyReadTreeSet deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken jsonToken = jsonParser.currentToken();
                if(jsonToken == null) {
                    jsonToken = jsonParser.nextToken();
                }
                if(jsonToken == JsonToken.START_ARRAY) {
                    Set set = new HashSet<>();
                    try {
                        JsonKit.collectionParseToken(jsonParser, set);
                        return new OnlyReadTreeSet<>(set);
                    } catch (ClassCastException e) {
                        JsonKit.collectionParseToken(jsonParser, set);
                        return new OnlyReadTreeSet<>(DeserializerHandler.getDefaultComparator(), set);
                    }
                }
                throw new ClassCastException("无法将对象类型的 JSON 字符串转为 com.tools.common.container.r.OnlyReadTreeSet 实例");
            }
        };
    }


    @Note("处理、转换获取 TreeSet 实例")
    public static StdDeserializer<TreeSet> treeSetDeserializer() {
        return new StdDeserializer<TreeSet>(TreeSet.class) {
            @Override
            public TreeSet deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken jsonToken = jsonParser.currentToken();
                if(jsonToken == null) {
                    jsonToken = jsonParser.nextToken();
                }
                if(jsonToken == JsonToken.START_ARRAY) {
                    TreeSet set = new TreeSet<>();
                    try {
                        JsonKit.collectionParseToken(jsonParser, set);
                        return set;
                    } catch (ClassCastException e) {
                        TreeSet treeSet = new TreeSet(DeserializerHandler.getDefaultComparator());
                        treeSet.addAll(set);
                        JsonKit.collectionParseToken(jsonParser, treeSet);
                        return treeSet;
                    }
                }
                throw new ClassCastException("无法将对象类型的 JSON 字符串转为 java.util.TreeSet 实例");
            }
        };
    }


    @Note("处理、转换获取 ConcurrentSkipListSet 实例")
    public static StdDeserializer<ConcurrentSkipListSet> concurrentSkipListSetDeserializer() {
        return new StdDeserializer<ConcurrentSkipListSet>(ConcurrentSkipListSet.class) {
            @Override
            public ConcurrentSkipListSet deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken jsonToken = jsonParser.currentToken();
                if(jsonToken == null) {
                    jsonToken = jsonParser.nextToken();
                }
                if(jsonToken == JsonToken.START_ARRAY) {
                    ConcurrentSkipListSet set = new ConcurrentSkipListSet<>();
                    try {
                        JsonKit.collectionParseToken(jsonParser, set);
                        return set;
                    } catch (ClassCastException e) {
                        ConcurrentSkipListSet treeSet = new ConcurrentSkipListSet(DeserializerHandler.getDefaultComparator());
                        treeSet.addAll(set);
                        JsonKit.collectionParseToken(jsonParser, treeSet);
                        return treeSet;
                    }
                }
                throw new ClassCastException("无法将对象类型的 JSON 字符串转为 java.util.concurrent.ConcurrentSkipListSet 实例");
            }
        };
    }
}
